<template>
	<el-upload
		:file-list="infoList"
		:action="actionUrl"
		:limit="limit"
		:disabled="disabled"
		list-type="picture-card"
		:auto-upload="true"
		:multiple="false"
		:data="basedata"
		:accept="accept"
		:on-preview="handlePictureCardPreview"
		:on-remove="handleRemove"
		:before-upload="beforeUpload"
		:on-success="upSuccess"
		:http-request="handleUpload"
		:class="{ limitOpctin: limit === infoList.length }"
	>
		<template #tip>
			<div class="tips">
				{{ tips }}
			</div>
		</template>
		<el-icon>
			<Plus />
		</el-icon>
	</el-upload>

	<el-dialog v-model="dialogVisible">
		<img style="width: 100%" w-full :src="dialogImageUrl" alt="图片预览" />
	</el-dialog>
</template>

<script setup lang="ts">
/*
example: <UpLoad :limit='1' v-model:fileLists='ruleForm.fileLists' accept='image/png,image/jpg'/>
*/
import { UploadProps, UploadUserFile, UploadRawFile, UploadFile, UploadFiles, ElMessage } from 'element-plus';
import { onMounted, ref, watch } from 'vue';
import { useCommonApi } from '/@/api/common';
import { Plus } from '@element-plus/icons-vue';
import axios from 'axios';

interface Props {
	limit?: number;
	accept?: string;
	tips?: string;
	fileLists?: UploadUserFile[];
	disabled?: boolean;
	sizeMax?: number;
	fileType?: string;
}

const props = withDefaults(defineProps<Props>(), {
	limit: 9,
	accept: 'image/png,image/jpeg,image/gif,image/jpg',
	tips: '',
	fileLists: () => [],
	disabled: false,
	sizeMax: 5,
	fileType: 'img',
});

const emit = defineEmits(['update:fileLists']);

const infoList = ref<any>([]);
const dialogImageUrl = ref('');
const fileName = ref('');
const Expires = ref('');
const percent = ref(0);
const actionUrl = ref('');
const dialogVisible = ref(false);
let basedata = ref<any>(null);

// onMounted(() => {
// 	infoList.value = props.fileLists || [];
// });

watch(
	() => props.fileLists,
	(nVal) => {
		infoList.value = nVal;
	},
	{
		immediate: true,
	}
);

const handleRemove = (uploadFile: any) => {
	infoList.value.forEach((v: any, i: any) => {
		if (v.uid == uploadFile.uid) {
			infoList.value.splice(i, 1);
		}
	});
	emit('update:fileLists', infoList.value);
};

const handlePictureCardPreview = (uploadFile: any) => {
	dialogImageUrl.value = uploadFile.url;
	dialogVisible.value = true;
};

const upSuccess = (res: any, file: UploadFile, uploadFiles: UploadFiles) => {
	console.log('file>>>>>>>>>', file);

	infoList.value = [
		...infoList.value,
		{
			// url: `${OSS_FLAG.host}/${basedata.value.key}?OSSAccessKeyId=${basedata.value.OSSAccessKeyId}&Expires=${Expires.value}&Signature=${basedata.value.signature}`,
			url: file.url, //由于图片会过期，所以url使用本地图片路径
			name: fileName.value,
			fileName: basedata.value.key,
			// url: 'https://snc-ai-prod-oss.oss-cn-hangzhou.aliyuncs.com/gamehub/1663662037237avatar.png?OSSAccessKeyId=LTAI5tHB6AeMcUBz85fxHjm6&Expires=1663671680&Signature=v%2FVJDq4F7HcDzcNqiV6NfxtnBmg%3D'
		},
	];
	emit('update:fileLists', infoList.value);
};
const random_string = (len = 32) => {
	const chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
	const maxPos = chars.length;
	let pwd = '';
	for (let i = 0; i < len; i++) {
		pwd += chars.charAt(Math.floor(Math.random() * maxPos));
	}
	return pwd;
};
const get_suffix = (filename: string) => {
	const pos = filename.lastIndexOf('.');
	let suffix = '';
	if (pos != -1) {
		suffix = filename.substring(pos);
	}
	return suffix;
};
const calculate_object_name = (dir: string, filename: string) => {
	let suffix = get_suffix(filename);
	return dir + random_string(10) + suffix;
};

const beforeUpload = async (rawFile: UploadRawFile) => {
	const { size, name, uid } = rawFile;

	if (size / 1024 / 1024 > props.sizeMax) {
		ElMessage.error(`文件大小超过了 ${props.sizeMax}MB!`);
		return false;
	}
	//以下处理一定要加，不然会出现问题1
	try {
		const { result: data } = await useCommonApi().oss();
		fileName.value = rawFile.name;
		Expires.value = data.expire;
		actionUrl.value = data.host;
		basedata.value = {
			key: calculate_object_name(data.dir, rawFile.name),
			success_action_status: '200',
			policy: data.policy,
			OSSAccessKeyId: data.accessid,
			signature: data.signature,
		};

		return true;
	} catch (err) {
		return false;
	}
};

const handleUpload = (object: any) => {
	let formdata = new FormData();
	formdata.append('OSSAccessKeyId', basedata.value.OSSAccessKeyId);
	formdata.append('success_action_status', basedata.value.success_action_status);
	formdata.append('policy', basedata.value.policy);
	formdata.append('Signature', basedata.value.signature);
	formdata.append('key', basedata.value.key);
	// formdata.append('callback',basedata.value.callback);
	formdata.append('file', object.file); //file 一定要在 key 之后 不然会报错😂
	axios({
		url: actionUrl.value,
		method: 'post',
		data: formdata,
		headers: {
			'Content-Type': 'multipart/form-data',
		},
	}).then((res) => {
		if (res.status == 200) {
			object.onSuccess(res);
		} else {
			ElMessage({ message: '上传失败', type: 'error', showClose: true });
		}
	});
};
</script>

<style lang="scss" scoped>
.limitOpctin :deep(.ep-upload--picture-card) {
	display: none !important;
}

:deep(.ep-upload-list__item .ep-icon--close-tip) {
	display: none !important;
}

.tips {
	color: #999 !important;
	font-size: 12px;
}
</style>
